home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / glibc108.zip / glibc108 / time / zdump.c < prev    next >
C/C++ Source or Header  |  1994-05-10  |  7KB  |  308 lines

  1. #ifndef lint
  2. #ifndef NOID
  3. static char    elsieid[] = "@(#)zdump.c    7.10";
  4. #endif /* !defined NOID */
  5. #endif /* !defined lint */
  6.  
  7. /*
  8. ** This code has been made independent of the rest of the time
  9. ** conversion package to increase confidence in the verification it provides.
  10. ** You can use this code to help in verifying other implementations.
  11. */
  12.  
  13. #include "stdio.h"    /* for stdout, stderr */
  14. #include "string.h"    /* for strcpy */
  15. #include "sys/types.h"    /* for time_t */
  16. #include "time.h"    /* for struct tm */
  17.  
  18. #ifndef MAX_STRING_LENGTH
  19. #define MAX_STRING_LENGTH    1024
  20. #endif /* !defined MAX_STRING_LENGTH */
  21.  
  22. #ifndef TRUE
  23. #define TRUE        1
  24. #endif /* !defined TRUE */
  25.  
  26. #ifndef FALSE
  27. #define FALSE        0
  28. #endif /* !defined FALSE */
  29.  
  30. #ifndef EXIT_SUCCESS
  31. #define EXIT_SUCCESS    0
  32. #endif /* !defined EXIT_SUCCESS */
  33.  
  34. #ifndef EXIT_FAILURE
  35. #define EXIT_FAILURE    1
  36. #endif /* !defined EXIT_FAILURE */
  37.  
  38. #ifndef SECSPERMIN
  39. #define SECSPERMIN    60
  40. #endif /* !defined SECSPERMIN */
  41.  
  42. #ifndef MINSPERHOUR
  43. #define MINSPERHOUR    60
  44. #endif /* !defined MINSPERHOUR */
  45.  
  46. #ifndef SECSPERHOUR
  47. #define SECSPERHOUR    (SECSPERMIN * MINSPERHOUR)
  48. #endif /* !defined SECSPERHOUR */
  49.  
  50. #ifndef HOURSPERDAY
  51. #define HOURSPERDAY    24
  52. #endif /* !defined HOURSPERDAY */
  53.  
  54. #ifndef EPOCH_YEAR
  55. #define EPOCH_YEAR    1970
  56. #endif /* !defined EPOCH_YEAR */
  57.  
  58. #ifndef TM_YEAR_BASE
  59. #define TM_YEAR_BASE    1900
  60. #endif /* !defined TM_YEAR_BASE */
  61.  
  62. #ifndef DAYSPERNYEAR
  63. #define DAYSPERNYEAR    365
  64. #endif /* !defined DAYSPERNYEAR */
  65.  
  66. #ifndef isleap
  67. #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
  68. #endif /* !defined isleap */
  69.  
  70. extern char **    environ;
  71. extern int    getopt();
  72. extern char *    optarg;
  73. extern int    optind;
  74. extern time_t    time();
  75. extern char *    tzname[2];
  76. extern void    tzset();
  77.  
  78. #ifdef USG
  79. extern void    exit();
  80. extern void    perror();
  81. #endif /* defined USG */
  82.  
  83. static char *    abbr();
  84. static long    delta();
  85. static time_t    hunt();
  86. static int    longest;
  87. static char *    progname;
  88. static void    show();
  89.  
  90. int
  91. main(argc, argv)
  92. int    argc;
  93. char *    argv[];
  94. {
  95.     register int    i, c;
  96.     register int    vflag;
  97.     register char *    cutoff;
  98.     register int    cutyear;
  99.     register long    cuttime;
  100.     time_t        now;
  101.     time_t        t, newt;
  102.     time_t        hibit;
  103.     struct tm    tm, newtm;
  104.  
  105.     progname = argv[0];
  106.     vflag = 0;
  107.     cutoff = NULL;
  108.     while ((c = getopt(argc, argv, "c:v")) == 'c' || c == 'v')
  109.         if (c == 'v')
  110.             vflag = 1;
  111.         else    cutoff = optarg;
  112.     if (c != EOF ||
  113.         (optind == argc - 1 && strcmp(argv[optind], "=") == 0)) {
  114.             (void) fprintf(stderr,
  115. "%s: usage is %s [ -v ] [ -c cutoff ] zonename ...\n",
  116.                 argv[0], argv[0]);
  117.             (void) exit(EXIT_FAILURE);
  118.     }
  119.     if (cutoff != NULL) {
  120.         int    y;
  121.  
  122.         cutyear = atoi(cutoff);
  123.         cuttime = 0;
  124.         for (y = EPOCH_YEAR; y < cutyear; ++y)
  125.             cuttime += DAYSPERNYEAR + isleap(y);
  126.         cuttime *= SECSPERHOUR * HOURSPERDAY;
  127.     }
  128.     (void) time(&now);
  129.     longest = 0;
  130.     for (i = optind; i < argc; ++i)
  131.         if (strlen(argv[i]) > longest)
  132.             longest = strlen(argv[i]);
  133.     for (hibit = 1; (hibit << 1) != 0; hibit <<= 1)
  134.         continue;
  135.     for (i = optind; i < argc; ++i) {
  136.         register char **    saveenv;
  137.         static char        buf[MAX_STRING_LENGTH];
  138.         char *            fakeenv[2];
  139.  
  140.         if (strlen(argv[i]) + 4 > sizeof buf) {
  141.             (void) fflush(stdout);
  142.             (void) fprintf(stderr, "%s: argument too long -- %s\n",
  143.                 progname, argv[i]);
  144.             (void) exit(EXIT_FAILURE);
  145.         }
  146.         (void) strcpy(buf, "TZ=");
  147.         (void) strcat(buf, argv[i]);
  148.         fakeenv[0] = buf;
  149.         fakeenv[1] = NULL;
  150.         saveenv = environ;
  151.         environ = fakeenv;
  152.         (void) tzset();
  153.         environ = saveenv;
  154.         show(argv[i], now, FALSE);
  155.         if (!vflag)
  156.             continue;
  157.         /*
  158.         ** Get lowest value of t.
  159.         */
  160.         t = hibit;
  161.         if (t > 0)        /* time_t is unsigned */
  162.             t = 0;
  163.         show(argv[i], t, TRUE);
  164.         t += SECSPERHOUR * HOURSPERDAY;
  165.         show(argv[i], t, TRUE);
  166.         tm = *localtime(&t);
  167.         (void) strncpy(buf, abbr(&tm), (sizeof buf) - 1);
  168.         for ( ; ; ) {
  169.             if (cutoff != NULL && t >= cuttime)
  170.                 break;
  171.             newt = t + SECSPERHOUR * 12;
  172.             if (cutoff != NULL && newt >= cuttime)
  173.                 break;
  174.             if (newt <= t)
  175.                 break;
  176.             newtm = *localtime(&newt);
  177.             if (delta(&newtm, &tm) != (newt - t) ||
  178.                 newtm.tm_isdst != tm.tm_isdst ||
  179.                 strcmp(abbr(&newtm), buf) != 0) {
  180.                     newt = hunt(argv[i], t, newt);
  181.                     newtm = *localtime(&newt);
  182.                     (void) strncpy(buf, abbr(&newtm),
  183.                         (sizeof buf) - 1);
  184.             }
  185.             t = newt;
  186.             tm = newtm;
  187.         }
  188.         /*
  189.         ** Get highest value of t.
  190.         */
  191.         t = ~((time_t) 0);
  192.         if (t < 0)        /* time_t is signed */
  193.             t &= ~hibit;
  194.         t -= SECSPERHOUR * HOURSPERDAY;
  195.         show(argv[i], t, TRUE);
  196.         t += SECSPERHOUR * HOURSPERDAY;
  197.         show(argv[i], t, TRUE);
  198.     }
  199.     if (fflush(stdout) || ferror(stdout)) {
  200.         (void) fprintf(stderr, "%s: Error writing standard output ",
  201.             argv[0]);
  202.         (void) perror("standard output");
  203.         (void) exit(EXIT_FAILURE);
  204.     }
  205.     exit(EXIT_SUCCESS);
  206.  
  207.     /* gcc -Wall pacifier */
  208.     for ( ; ; )
  209.         continue;
  210. }
  211.  
  212. static time_t
  213. hunt(name, lot, hit)
  214. char *    name;
  215. time_t    lot;
  216. time_t    hit;
  217. {
  218.     time_t        t;
  219.     struct tm    lotm;
  220.     struct tm    tm;
  221.     static char    loab[MAX_STRING_LENGTH];
  222.  
  223.     lotm = *localtime(&lot);
  224.     (void) strncpy(loab, abbr(&lotm), (sizeof loab) - 1);
  225.     while ((hit - lot) >= 2) {
  226.         t = lot / 2 + hit / 2;
  227.         if (t <= lot)
  228.             ++t;
  229.         else if (t >= hit)
  230.             --t;
  231.         tm = *localtime(&t);
  232.         if (delta(&tm, &lotm) == (t - lot) &&
  233.             tm.tm_isdst == lotm.tm_isdst &&
  234.             strcmp(abbr(&tm), loab) == 0) {
  235.                 lot = t;
  236.                 lotm = tm;
  237.         } else    hit = t;
  238.     }
  239.     show(name, lot, TRUE);
  240.     show(name, hit, TRUE);
  241.     return hit;
  242. }
  243.  
  244. /*
  245. ** Thanks to Paul Eggert (eggert@twinsun.com) for logic used in delta.
  246. */
  247.  
  248. static long
  249. delta(newp, oldp)
  250. struct tm *    newp;
  251. struct tm *    oldp;
  252. {
  253.     long    result;
  254.     int    tmy;
  255.  
  256.     if (newp->tm_year < oldp->tm_year)
  257.         return -delta(oldp, newp);
  258.     result = 0;
  259.     for (tmy = oldp->tm_year; tmy < newp->tm_year; ++tmy)
  260.         result += DAYSPERNYEAR + isleap(tmy + TM_YEAR_BASE);
  261.     result += newp->tm_yday - oldp->tm_yday;
  262.     result *= HOURSPERDAY;
  263.     result += newp->tm_hour - oldp->tm_hour;
  264.     result *= MINSPERHOUR;
  265.     result += newp->tm_min - oldp->tm_min;
  266.     result *= SECSPERMIN;
  267.     result += newp->tm_sec - oldp->tm_sec;
  268.     return result;
  269. }
  270.  
  271. static void
  272. show(zone, t, v)
  273. char *    zone;
  274. time_t    t;
  275. int    v;
  276. {
  277.     struct tm *        tmp;
  278.     extern struct tm *    localtime();
  279.  
  280.     (void) printf("%-*s  ", longest, zone);
  281.     if (v)
  282.         (void) printf("%.24s GMT = ", asctime(gmtime(&t)));
  283.     tmp = localtime(&t);
  284.     (void) printf("%.24s", asctime(tmp));
  285.     if (*abbr(tmp) != '\0')
  286.         (void) printf(" %s", abbr(tmp));
  287.     if (v) {
  288.         (void) printf(" isdst=%d", tmp->tm_isdst);
  289. #ifdef TM_GMTOFF
  290.         (void) printf(" gmtoff=%ld", tmp->TM_GMTOFF);
  291. #endif /* defined TM_GMTOFF */
  292.     }
  293.     (void) printf("\n");
  294. }
  295.  
  296. static char *
  297. abbr(tmp)
  298. struct tm *    tmp;
  299. {
  300.     register char *    result;
  301.     static char    nada[1];
  302.  
  303.     if (tmp->tm_isdst != 0 && tmp->tm_isdst != 1)
  304.         return nada;
  305.     result = tzname[tmp->tm_isdst];
  306.     return (result == NULL) ? nada : result;
  307. }
  308.